﻿
using Abp.Domain.Repositories;
using Abp.EntityFrameworkCore.Repositories;
using Abp.UI;
using SOEI.Solution.CommonOthers.WaterImage.Enum;
using SOEI.Solution.CommonOthers.WaterImage.StructEntities;
using SOEI.Solution.Helper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace SOEI.Solution.CommonOthers.WaterImage.DomainService
{
    public class WaterImageManager : DomainServiceBase, IWaterImageManager
    {

        private readonly IRepository<Default> _repository;

        public WaterImageManager(IRepository<Default> repository)
        {
            _repository = repository;
        }

        #region 接口实现

        /// <summary>获取水印图片
        /// </summary>
        public async Task<byte[]> GetWaterImage(WaterImageParam pParam)
        {
            if(pParam == null)
            {
                throw new UserFriendlyException("参数不能为空！");
            }
            switch (pParam.Type)
            {
                case WaterType.监管协议:
                    return await GetWaterImageForAgreement(pParam);
                default:
                    throw new UserFriendlyException("暂不支持该水印类型！");
            }
        }

        /// <summary>创建水印并保存
        /// </summary>
        public async Task CreateWaterImage(WaterImageParam pParam)
        {
            if(pParam == null)
            {
                throw new UserFriendlyException("参数不能为空！");
            }

            switch (pParam.Type)
            {
                case WaterType.监管协议:
                    await CreateWaterImageForAgreement(pParam);
                    break;
            }
        }

        

        #endregion

        #region 生成水印图片方法

        /// <summary>根据水印编号生成水印图片
        /// </summary>
        protected byte[] GenerateWaterImage(string pCode)
        {
            try
            {
                Bitmap image = new Bitmap(900, 1000);

                Graphics g = Graphics.FromImage(image);
                GraphicsPath gp = new GraphicsPath();
                g.Clear(Color.Blue);

                char[] code = pCode.ToCharArray(); //文字
                Font myFont = new Font("宋体", 80);
                float angle = -30; //角度
                float l = 0;
                Random rnd = new Random();

                SizeF size = g.MeasureString(pCode, myFont);
                g.TranslateTransform(l + size.Width / 2, size.Height / 2); //设置旋转中心为文字中心
                g.RotateTransform((float)(angle)); //旋转

                gp.AddString(pCode, new FontFamily("宋体"), (int)FontStyle.Bold, 110, new PointF(-300, 320), StringFormat.GenericDefault);

                g.DrawPath(new Pen(Color.FromArgb(255, 110, 100, 100)), gp);

                image = MakeTransparentGif(image, Color.Blue);

                MemoryStream ms = null;
                byte[] ByteImage;
                ms = new MemoryStream();
                image.Save(ms, ImageFormat.Gif);
                ByteImage = new Byte[ms.Length];
                ByteImage = ms.ToArray();
                ms.Close();
                g.Dispose();

                return ByteImage;
            }
            catch { }

            return new byte[] { };
        }

        /// <summary>GIF图片背景透明 
        /// </summary>
		protected Bitmap MakeTransparentGif(Bitmap bitmap, Color color)
        {
            byte R = color.R;
            byte G = color.G;
            byte B = color.B;

            MemoryStream fin = new MemoryStream();
            bitmap.Save(fin, System.Drawing.Imaging.ImageFormat.Gif);

            MemoryStream fout = new MemoryStream((int)fin.Length);
            int count = 0;
            byte[] buf = new byte[256];
            byte transparentIdx = 0;
            fin.Seek(0, SeekOrigin.Begin);
            //header
            count = fin.Read(buf, 0, 13);
            if ((buf[0] != 71) || (buf[1] != 73) || (buf[2] != 70)) return null; //GIF

            fout.Write(buf, 0, 13);

            int i = 0;
            if ((buf[10] & 0x80) > 0)
            {
                i = 1 << ((buf[10] & 7) + 1) == 256 ? 256 : 0;
            }

            for (; i != 0; i--)
            {
                fin.Read(buf, 0, 3);
                if ((buf[0] == R) && (buf[1] == G) && (buf[2] == B))
                {
                    transparentIdx = (byte)(256 - i);
                }
                fout.Write(buf, 0, 3);
            }

            bool gcePresent = false;
            while (true)
            {
                fin.Read(buf, 0, 1);
                fout.Write(buf, 0, 1);
                if (buf[0] != 0x21) break;
                fin.Read(buf, 0, 1);
                fout.Write(buf, 0, 1);
                gcePresent = (buf[0] == 0xf9);
                while (true)
                {
                    fin.Read(buf, 0, 1);
                    fout.Write(buf, 0, 1);
                    if (buf[0] == 0) break;
                    count = buf[0];
                    if (fin.Read(buf, 0, count) != count) return null;
                    if (gcePresent)
                    {
                        if (count == 4)
                        {
                            buf[0] |= 0x01;
                            buf[3] = transparentIdx;
                        }
                    }
                    fout.Write(buf, 0, count);
                }
            }
            while (count > 0)
            {
                count = fin.Read(buf, 0, 1);
                fout.Write(buf, 0, 1);
            }
            fin.Close();
            fout.Flush();

            return new Bitmap(fout);
        }

        #endregion

        #region 监管协议水印方法

        /// <summary>创建水印的整体流程
        /// </summary>
        protected async Task CreateWaterImageForAgreement(WaterImageParam pParam)
        {
            var vParam = ParamCollect.FromObj(new
            {
                IS_JGXYBH = pParam.YWBH,
                IS_LRR = base.CurrentUser.Id.ToString(),
                IS_LRRXM = base.CurrentUser.UserName,
                IS_SFBG = pParam.SFBG
            }, ParameterDirection.Input);

            vParam.Add("IS_SYBH", ParameterDirection.Output);

            await _repository.GetDbContext().Database.ExecuteStoreProcedure(Package.PKG_CLFZJJGXX + "SP_GET_SYBH", vParam);

            string vSYBH = vParam["IS_SYBH"].Value as string;

            byte[] vData = GenerateWaterImage(vSYBH);

            vParam = ParamCollect.FromObj(new {
                IS_HTDJH = pParam.YWBH,
                IB_SYTP = vData,
                IS_SFBG = pParam.SFBG
            });

            await _repository.GetDbContext().Database.ExecuteStoreProcedure(Package.PKG_CLFZJJGXX + "SP_SAVEWATERIMG", vParam);

        }

        /// <summary>获取监管协议水印图像
        /// </summary>
        protected async Task<byte[]> GetWaterImageForAgreement(WaterImageParam pParam)
        {
            var vParam = ParamCollect.FromObj(new 
            {
                IS_HTDJH = pParam.YWBH,
                IS_SFBG = pParam.SFBG
            });

            var ds = await _repository.GetDbContext().Database.ExecuteStoreProcedure(Package.PKG_CLFZJJGXX + "SP_GET_WATERIMG", vParam, "CURSOR");

            if (ds.HasRowRecord())
            {
                var vObj = ds.Tables[0].Rows[0]["SYTP"];

                if(vObj != DBNull.Value)
                {
                    return vObj as byte[];
                }
            }

            return new byte[] { };
        }

        #endregion
    }
}
